/**
 * 类型断言 能够显式告知 "类型检查程序" 当前这个变量的类型，可以进行类型分析地修正、类型
 * 类型断言 就是一个将 变量的已有类型 更改为 新指定类型 的操作
 * 类型断言的正确使用方式是，在 TypeScript 类型分析不正确或不符合预期时，将其断言为此处的正确类型
 * 基本语法是 as NewType 或者 <NewType>值。<NewType>值 语法，书写更简洁
 * 但是在React 的 TSX 中 <NewType>值 语法，并不能很好地被分析出来。
*/

//1、将 any / unknown 类型断言到一个具体的类型
let unknownVar: unknown;
(unknownVar as { A: () => {} }).A();

//2、可以 as 到 any 来跳过所有的类型检查：
const str: string = "hanxuming";
(str as any).func().A().prop;

//3、可以在联合类型中断言一个具体的分支，但是 不能将联合类型断言为不存在的类型：
function A(union: string | number) {
    if ((union as string).includes("hanxuming")) { }
    if ((union as number).toFixed() === '599') { }
}

//4、将一个父类断言为更加具体的子类
interface ApiError extends Error {
    code: number;
}
interface HttpError extends Error {
    statusCode: number;
}
function isApiError(error: Error) {
    if (typeof (error as ApiError).code === 'number') {
        return true;
    }
    return false;
}

//5、类型断言还有一种用法是作为代码提示的辅助工具，比如对于以下这个稍微复杂的接口：
interface IStruct {
    foo: string;
    bar: {
        barPropA: string;
        barPropB: number;
        barMethod: () => void;
        baz: {
            handler: () => Promise<void>;
        };
    };
}
//这个时候有一堆类型报错，必须实现整个接口结构才可以
const obj: IStruct = {};
//但如果使用类型断言，可以在 保留类型提示 的前提下，不那么完整地实现这个结构：
const objA = <IStruct>{
    bar: {
        baz: {},
    },
};

//export {}：解决“无法重新声明块范围变量”错误提示问题
export { }